package com.net.rip.utils;

import com.net.rip.entity.Information;
import com.net.rip.entity.Network;
import com.net.rip.entity.Router;

import java.io.*;
import java.util.List;
import java.util.Scanner;

/**
 * 路由信息更新
 */
public class tableUpdate {
    /**
     * 根据循环轮次更新路由表
     *
     * @param network
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static void doUpdate(Network network) throws IOException, ClassNotFoundException {

        System.out.print("请输入循环轮次:");
        Scanner in = new Scanner(System.in);
        int sum = in.nextInt();
        for (int a = 0; a < sum; a++) {
            System.out.println("---循环轮次" + (a + 1) + "---");
            tableupdate(network);
            for (int i = 0; i < network.getRouterNum(); i++) {
                System.out.println(network.getRouterList().get(i));
            }
        }
    }

    /**
     * RIP协议更新：
     * 1、仅和相邻路由器交换信息
     * 2、交换信息为自己的路由表
     * 3、按固定时间，这里为轮次
     *
     * @param network
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static void tableupdate(Network network) throws IOException, ClassNotFoundException {
        List<Router> routerList = network.getRouterList();
        //从当前网络第一个路由器开始遍历查询
        for (int i = 0; i < routerList.size(); i++) {
            //当前路由器
            Router router = routerList.get(i);
            List<Router> nearRouterList = routerList.get(i).getNearRouter();
            //遍历当前路由器的所有邻居路由器
            for (int j = 0; j < nearRouterList.size(); j++) {
                Router nearRouter = nearRouterList.get(j);

                //如果没有信息，什么也不做
                if (nearRouter.getInformation().isEmpty() || nearRouter.getInformation().size() == 0 || router == nearRouter) {
                    break;
                }

                //对nearRouter的复制，避免直接修改路由器nearRouter的路由表
                //这里要使用深拷贝,不能影响源对象的值
                Router nearRouterBackUp = nearRouter.myclone();

                for (Information information : nearRouterBackUp.getInformation().values()) {
                    //最大跳数15
                    if (information.getDistance() < 16) {
                        information.setDistance(information.getDistance() + 1);
                    }
                    information.setNextJumpRouter(nearRouterBackUp.getRouterName());
                }

                Information information = null;
                for (String s : nearRouterBackUp.getInformation().keySet()) {
                    //原路由表中不包括目的网络,则直接添加到路由表中
                    if (!router.getInformation().containsKey(s)) {
                        information = new Information(s, nearRouterBackUp.getInformation().get(s).getDistance(), nearRouterBackUp.getRouterName());
                        router.getInformation().put(s, information);
                    } else {
                        //如果下一跳相同，替换原路由表中的项目
                        if (router.getInformation().get(s).getNextJumpRouter().equals(nearRouterBackUp.getRouterName())) {
                            router.getInformation().put(s, nearRouterBackUp.getInformation().get(s));
                        } else {
                            //若收到的项目中的距离小于路由表中的距离，则进行更新
                            if (nearRouterBackUp.getInformation().get(s).getDistance() < router.getInformation().get(s).getDistance()) {
                                router.getInformation().put(s, nearRouterBackUp.getInformation().get(s));
                            }
                        }
                    }
                }
            }
        }
    }
}
